﻿using Microsoft.EntityFrameworkCore;
using RBACProject.Domian;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace RBACProject.Repositories
{
                                                                       //  new()  泛型约束 允许实例化
    public class BaseRepository<TEntity> :  IBaseRepository<TEntity> where TEntity : class, new()  
    {
        /// <summary>
        /// 构造函数依赖注入
        /// </summary>
        /// <param name="db"></param>
        public BaseRepository(MyDbContext db)
        {
            Db = db;
        }
        /// <summary>
        /// 获取属性
        /// </summary>
        public MyDbContext Db { get; }


        #region 添加

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TEntity Insert(TEntity entity)
        {
            Db.Set<TEntity>().Add(entity);
            Db.SaveChanges();
            return entity;
        }

        /// <summary>
        /// 添加  (异步)
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<TEntity> InsertAsync(TEntity entity)
        {
            await Db.Set<TEntity>().AddAsync(entity);
            await Db.SaveChangesAsync();
            return entity;
        }

        /// <summary>
        /// 批量添加 (异步)
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public async Task<int> InsertManyAsync(List<TEntity> entities)
        {
            await Db.Set<TEntity>().AddRangeAsync(entities);
            return await Db.SaveChangesAsync();
        }
        #endregion



        #region 删除

        /// <summary>
        /// 单个删除    按照主键Id  (异步)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<int> DeleteAsyncById(int id)
        {
            var data = await Db.Set<TEntity>().FindAsync(id);
            Db.Set<TEntity>().Remove(data);
            return await Db.SaveChangesAsync();
        }

        /// <summary>
        ///  删除    根据条件 (异步)
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>  
                                       //是一个表示带有参数的 lambda 表达式的委托类型
        public async Task<int> DeleteAsyncWhere(Expression<Func<TEntity, bool>> predicate)   
        {
            var list = await Db.Set<TEntity>().Where(predicate).ToListAsync();
            Db.Set<TEntity>().RemoveRange(list);
            return await Db.SaveChangesAsync();
        }

        /// <summary>
        /// 批量删除  (异步)
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public async Task<int> BathDeleteAsync(List<TEntity> entities)
        {
            Db.Set<TEntity>().RemoveRange(entities);
            return await Db.SaveChangesAsync();
        }
        #endregion


        /// <summary>
        /// 更新（修改）  (异步)
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<TEntity> UpdateAsnyc(TEntity entity)
        {
            Db.Set<TEntity>().Update(entity);
            await Db.SaveChangesAsync();
            return entity;
        }


        #region 查询

        /// <summary>
        /// 查询  全部
        /// </summary>
        /// <returns>返回一个泛型</returns>
        public IQueryable<TEntity> QueryAsnycAll()
        {
            return Db.Set<TEntity>().AsQueryable();
        }

        /// <summary>
        /// 查询  按主键  (异步)
        /// </summary>
        /// <param name="id">主键编号</param>
        /// <returns>返回实体</returns>
        public async Task<TEntity> QueryAsnycById(int id)
        {
            return await Db.Set<TEntity>().FindAsync(id);
        }

        /// <summary>
        /// 查询  查询实体  (异步)
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns>返回实体</returns>
        public async Task<TEntity> QueryAsnycEntity(Expression<Func<TEntity, bool>> predicate)
        {
            return await Db.Set<TEntity>().FirstOrDefaultAsync(predicate);
        }


        /// <summary>
        /// 查询  按条件  (异步)
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns>返回实体集合</returns>
        public async Task<List<TEntity>> QueryWhere(Expression<Func<TEntity, bool>> predicate)
        {
            return await Db.Set<TEntity>().Where(predicate).ToListAsync();
        }

        /// <summary>
        /// 查询是否存在(异步)
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns>返回一个bool类型</returns>
        public async Task<bool> ExistsAsnyc(Expression<Func<TEntity, bool>> predicate)
        {
            return await Db.Set<TEntity>().AnyAsync(predicate);
        }     
        #endregion


            

    }
}
